package com.nit.bike.service.bike.impl;

import com.nit.bike.dto.basic.BikeDTO;
import com.nit.bike.dto.basic.UserDTO;
import com.nit.bike.dto.bike.CardDTO;
import com.nit.bike.dto.bike.CardRecordDTO;
import com.nit.bike.dto.bike.RideDTO;
import com.nit.bike.dto.utils.OpResultDTO;
import com.nit.bike.entity.bike.CardEntity;
import com.nit.bike.entity.bike.RideEntity;
import com.nit.bike.mapper.basic.BikeMapper;
import com.nit.bike.mapper.bike.CardMapper;
import com.nit.bike.mapper.bike.RideMapper;
import com.nit.bike.service.basic.BikeService;
import com.nit.bike.service.basic.UserService;
import com.nit.bike.service.bike.CardRecordService;
import com.nit.bike.service.bike.CardService;
import com.nit.bike.service.bike.RideService;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

@Service
public class RideServiceImpl implements RideService {

    @Resource
    private RideMapper rideMapper;
    @Resource
    private BikeService bikeService;
    @Resource
    private UserService userService;
    @Resource
    private CardService cardService;
    @Resource
    private CardRecordService cardRecordService;

    @Override
    public RideDTO query(Long userId) throws Exception {
        RideDTO rideDTO = rideMapper.queryByUserId(userId);
        if (rideDTO != null) {
            rideDTO.setServerTime(new Date());
        }
        return rideDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpResultDTO add(RideDTO rideDTO) throws Exception {
        OpResultDTO op = new OpResultDTO();
        op.setMessage("error");
        MapperFactory factory;
        UserDTO userDTO = userService.getByUserId(rideDTO.getUserId());
        if (userDTO == null || userDTO.getUserState() == 2) {
            op.setResult("用户信息有误！");
            return op;
        }
        CardDTO cardDTO = cardService.query(rideDTO.getUserId());
        if (cardDTO == null || cardDTO.getCardState() != 0) {
            op.setResult("用户未绑定租借卡！");
            return op;
        }
        if (rideDTO.getRideType() == 0) {
            // 租用
            if (cardDTO.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
                op.setResult("用户余额不足！");
                return op;
            }
            if (userDTO.getRideId() != null) {
                op.setResult("正在骑行状态，无法再次租车！");
            } else {
                BikeDTO bikeDTO = bikeService.query(rideDTO.getBikeId());
                if (bikeDTO == null || bikeDTO.getBikeState() != 0) {
                    op.setResult("该车可能已被他人租用，您可以租用其他未使用的车辆");
                } else {
                    factory = new DefaultMapperFactory.Builder().build();
                    RideEntity entity = factory.getMapperFacade().map(rideDTO, RideEntity.class);
                    entity.setUserName(userDTO.getUserName());
                    entity.setBikeNumber(bikeDTO.getBikeNumber());
                    entity.setCardNumber(cardDTO.getCardNumber());
                    entity.setGmtCreate(new Date());
                    rideMapper.insertSelective(entity);
                    Long rideId = rideMapper.queryRideId();
                    userService.updateRideId(rideDTO.getUserId(), rideId);
                    bikeService.updateRideInfo(rideDTO.getBikeId(), rideId, bikeDTO.getStationId(), 1);
                    op.setMessage("success");
                }
            }
        } else if (rideDTO.getRideType() == 1) {
            // 归还
            if (userDTO.getRideId() == null) {
                op.setResult("未在骑行状态，无法进行还车");
            } else {
                RideDTO rideDTO2 = rideMapper.queryByIdFromUser(userDTO.getRideId());
                if (rideDTO2 == null || rideDTO2.getRideType() != 0) {
                    op.setResult("租借记录错误！");
                } else {
                    factory = new DefaultMapperFactory.Builder().build();
                    RideEntity entity = factory.getMapperFacade().map(rideDTO, RideEntity.class);
                    entity.setUserName(userDTO.getUserName());
                    entity.setBikeId(rideDTO2.getBikeId());
                    entity.setBikeNumber(rideDTO2.getBikeNumber());
                    entity.setCardNumber(cardDTO.getCardNumber());
                    Date now = new Date();
                    entity.setGmtCreate(now);
                    rideMapper.insertSelective(entity);
                    userService.updateRideId(rideDTO.getUserId(), null);
                    bikeService.updateRideInfo(rideDTO2.getBikeId(), null, rideDTO.getStationId(), 0);
                    CardRecordDTO cardRecordDTO = new CardRecordDTO();
                    cardRecordDTO.setCardId(cardDTO.getCardId());
                    cardRecordDTO.setCardNumber(cardDTO.getCardNumber());
                    cardRecordDTO.setUserId(rideDTO.getUserId());
                    cardRecordDTO.setRecordType(0);
                    cardRecordDTO.setBegRideId(rideDTO2.getRideId());
                    Long rideId = rideMapper.queryRideId();
                    cardRecordDTO.setEndRideId(rideId);
                    long during = (now.getTime() - rideDTO2.getGmtCreate().getTime()) / 60000 + 1;
                    cardRecordDTO.setDuring(during);
                    BigDecimal money = new BigDecimal(during < 240L ? during / 60 + 1 : 6);
                    cardRecordDTO.setMoney(money);
                    cardRecordService.add(cardRecordDTO);
                    op.setMessage("success");
                }
            }
        } else {
            op.setResult("参数有误！");
        }
        return op;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer update(RideDTO rideDTO) throws Exception {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer remove(String ids) throws Exception {
        return null;
    }
}
